import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@nestjs/jwt';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from 'src/users/entities/user.entity';
import { Repository } from 'typeorm';
import { SignInDto } from './dto/sign-in.dto';
import { SignUpDto } from './dto/sign-up.dto';
import { UnauthorizedException } from '@nestjs/common';
import { HashingService } from './hashing.service';
import { ActiveUserData } from './interfaces/active-user-data.interface';
// console.log('jwtConfig', jwtConfig.KEY);
@Injectable()
export class AuthService {
  constructor(
    @InjectRepository(User)
    private readonly userRepository: Repository<User>,
    private readonly jwtService: JwtService,
    // 依赖注入ConfigService
    private readonly configService: ConfigService,
    private readonly hashService: HashingService,
  ) {}
  // 用户注册
  async signUp(signUpDto: SignUpDto) {
    const { username, password } = signUpDto;
    const existingUser = await this.userRepository.findOne({
      where: [{ username }],
    });
    if (existingUser) throw new UnauthorizedException('User already exists');
    const hashedPassword = await this.hashService.hash(password);
    const user = this.userRepository.create({
      ...signUpDto,
      password: hashedPassword,
    });
    // return this.userRepository.save(user);
    console.log(user);
    return null;
  }
  async signIn(signInDto: SignInDto) {
    // todo: implement sign in logic
    const { username, password } = signInDto;
    const user = await this.userRepository.findOne({ where: [{ username }] });
    if (!user) throw new UnauthorizedException('User not found');
    const isMatch = await this.hashService.compare(password, user.password);
    if (!isMatch) throw new UnauthorizedException('Invalid credentials');
    return await this.generateToken(user);
  }

  async generateToken(user: User) {
    const token = await this.signToken<Partial<ActiveUserData>>(user.id, {
      username: user.username,
    });
    return { token };
  }

  async signToken<T>(userId: number, payload?: T) {
    // console.log(this.configService.get('jwt.secret'));
    return await this.jwtService.signAsync(
      {
        sub: userId,
        ...payload,
      },
      {
        secret: this.configService.get('jwt.secret'),
        expiresIn: this.configService.get('jwt.expiresIn'),
        issuer: this.configService.get('jwt.issuer'),
        audience: this.configService.get('jwt.audience'),
      },
    );
  }
}
